package com.nulldev.util.scripting.cup.vee.live_interp.gui;

import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import java.awt.BorderLayout;
import javax.swing.JTree;
import javax.swing.tree.DefaultTreeModel;

import com.nulldev.util.JVM.JVM;
import com.nulldev.util.VariableAPI.util.strings.splitters.Splitters;
import com.nulldev.util.data.Arrays.arrays.FastLists;
import com.nulldev.util.gui.swingAPI.Swing;
import com.nulldev.util.scripting.cup.instructions.CupInstruction;
import com.nulldev.util.scripting.cup.translators.cup_asm.CUPASMReader;
import com.nulldev.util.scripting.cup.vee.VEE;
import com.nulldev.util.scripting.cup.vee.CUPRegister;
import com.nulldev.util.scripting.cup.vee.CUPRegister.CUPRegisterType;
import com.nulldev.util.scripting.cup.vee.runner.CUPRunner;

import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.JButton;
import javax.swing.JTextPane;
import java.awt.event.ActionListener;
import java.util.List;
import java.util.Map.Entry;
import java.awt.event.ActionEvent;

public class VEELiveInterpreter extends JFrame {

	private static final long serialVersionUID = -5463189161571899507L;
	private JPanel contentPane;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		Swing.enableAA();
		Swing.enableJSO();
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					VEELiveInterpreter frame = new VEELiveInterpreter();
					frame.setVisible(true);
//					ThemeAPI.applySystemSwingTheme(frame, ThemingOptions.APPLY_SYSTEM_FONT);
					Swing.center(frame);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame.
	 */
	public VEELiveInterpreter() {
		setTitle("VEE: LiveInterpreter");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 450, 300);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));

		setContentPane(contentPane);
		contentPane.setLayout(new BorderLayout(0, 0));

		final DefaultMutableTreeNode dmtt = new DefaultMutableTreeNode("Registers") {
			private static final long serialVersionUID = -7749075873384439147L;

			{
				this.add(new DefaultMutableTreeNode("a: 0"));
				this.add(new DefaultMutableTreeNode("b: 0"));
				this.add(new DefaultMutableTreeNode("_VEEEM: 1"));
			}
		};

		final DefaultTreeModel model = new DefaultTreeModel(dmtt);

		final JTree tree = new JTree();
		tree.setModel(model);
		contentPane.add(tree, BorderLayout.EAST);

		JTextPane dtrpnRet = new JTextPane();
		dtrpnRet.setText("LNR a\n" + "INC a, 5\n" + "LNR b\n" + "PFCH b\n" + "ADD a, 5\n" + "MUL a, 3");
		contentPane.add(dtrpnRet, BorderLayout.CENTER);

		JButton btnExecute = new JButton("Execute");
		btnExecute.addActionListener(new ActionListener() {
			public void actionPerformed(final ActionEvent e) {
				try {
					final String payload = dtrpnRet.getText();
					final List<CupInstruction> insts = FastLists.list();
					for (final String line : Splitters.splitString(payload, "\n")) {
						final CupInstruction inst = CUPASMReader.translate(line);
						insts.add(inst);
					}
					JVM.println("Running " + insts.size() + " instruction(s).");
					final VEE vee = new VEE(CUPRegisterType.NORMAL);
					new CUPRunner(vee, insts).run();
					JVM.println("Execution completed.");
					dmtt.removeAllChildren();
					for (final Entry<Object, CUPRegister<?>> reg : vee.getRegisterManager().asMap().entrySet()) {
						dmtt.add(new DefaultMutableTreeNode(reg.getKey() + ": " + reg.getValue().get()));
					}
					model.setRoot(dmtt);
					tree.repaint();
				} catch (Exception ex) {
					JVM.errorln(ex);
				}
			}
		});
		contentPane.add(btnExecute, BorderLayout.SOUTH);
	}

}
